﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Web;
using CIAWorldMap;
using OSMLib;

/// <summary>
/// Summary description for ServerStatusController
/// </summary>
public class ServerStatusController
{
    readonly List<string> _reports = new List<string>();
    static DateTime _dtboot = DateTime.UtcNow;

    public string GetStatus()
    {
        _reports.Clear();
        _reports.Add("Application pool was started: "+  _dtboot.ToShortDateString() + " " + _dtboot.ToLongTimeString());
         _reports.Add("  UTC");
        DoMiscReport();

        var sb = new StringBuilder();
        foreach (var report in _reports)
        {
            string text2 = "" + HttpContext.Current.Server.HtmlEncode(report);
            sb.Append(text2);
            sb.Append("<br />");
        }
        return sb.ToString();
    }

    private void DoMiscReport()
    {
        DateTime dt;
       
        //http://msdn.microsoft.com/en-us/library/system.diagnostics.process.peakvirtualmemorysize64.aspx

        using (Process myProcess = Process.GetCurrentProcess())
        {
            //http://connect.microsoft.com/VisualStudio/feedback/details/329957/process-handlecount-is-not-accurate-in-real-time
            myProcess.Refresh(); // make the handle parameter not lie.

            dt = myProcess.StartTime;

            _reports.Add("");
            _reports.Add(string.Format("{0}", myProcess));
            _reports.Add(string.Format("  physical memory usage: {0}", myProcess.WorkingSet64));
            _reports.Add(string.Format("  base priority: {0}", myProcess.BasePriority));
            _reports.Add(string.Format("  priority class: {0}", myProcess.PriorityClass));
            _reports.Add(string.Format("  user processor time: {0}", myProcess.UserProcessorTime));
            _reports.Add(string.Format("  privileged processor time: {0}", myProcess.PrivilegedProcessorTime));
            _reports.Add(string.Format("  total processor time: {0}", myProcess.TotalProcessorTime));
            _reports.Add(string.Format("  PagedSystemMemorySize64: {0}", myProcess.PagedSystemMemorySize64));
            _reports.Add(string.Format("  PagedMemorySize64: {0}", myProcess.PagedMemorySize64));
            _reports.Add(string.Format("  Handle count: {0}", myProcess.HandleCount));
            _reports.Add(string.Format("  Thread count: {0}", myProcess.Threads.Count));
        }

        long memorySize = GC.GetTotalMemory(false);
        long memorySizet = GC.GetTotalMemory(true);

        _reports.Add(string.Format("  GC.GetTotalMemory(false): {0} MB", memorySize / 1000000));
        _reports.Add(string.Format("  GC.GetTotalMemory(true): {0} MB", memorySizet / 1000000));

        string text = "Started: ";
        text += dt.ToShortDateString();
        text += " ";
        text += dt.ToLongTimeString();
        text += " (local server time)";
        _reports.Add(text);

        _reports.Add("");
        TestFileAccess(_reports);
        _reports.Add("");
        SaveError(_reports);
    }

    static void TestFileAccess(List<string> reports)
    {
        try
        {
            var laosBorder = new LaosBorder();

            // good bug ! Don't replace the static ways!
            var waysTemp = new Dictionary<int, IOsmWay>();
            var namedNodesTemp = new List<IOsmNode>();

            var l = new OsmBinLoader(waysTemp, namedNodesTemp);

            if (File.Exists(@"c:\osm\osm.bin"))
            {
                reports.Add(@"c:\osm\osm.bin" + " exists");
                reports.Add("There are " + CountOfTiles(@"c:\osm\cache") + " tiles");
                reports.Add("");
                l.ReadFile(@"c:\osm\osm.bin");
                laosBorder.LoadBorder(@"c:\osm\border.bin");
            }
            else
            {
                reports.Add(@"f:\osm\osm.bin" + " exists");
                reports.Add("There are " + CountOfTiles(@"f:\osm\cache") + " tiles");
                reports.Add("");
                l.ReadFile(@"f:\osm\osm.bin");
                laosBorder.LoadBorder(@"f:\osm\border.bin");
            }

            reports.Add("Loaded " + waysTemp.Values.Count + " ways");
            reports.Add("Static " + Osm.Ways.Values.Count + " ways");

            reports.Add("Loaded " + namedNodesTemp.Count + " named nodes");
            reports.Add("Static " + Osm.NamedNodes.Count + " named nodes");

            reports.Add("Loaded " + laosBorder._geoPolygon.Count + " border points");
        }
        catch (Exception ex)
        {
            reports.Add("Test File Access Exception! " + ex.Message);
        }
    }

    private static int CountOfTiles(string path)
    {
        string[] files = Directory.GetFiles(path,
        "*.*",
        SearchOption.AllDirectories);

        return files.Length;
    }

    private static void SaveError(List<string> reports)
    {
        try
        {
            using (TextWriter newWriter = new StreamWriter("C:\\osm\\error.txt", true))
            {
                newWriter.WriteLine("test from server status");
                newWriter.Flush();
                newWriter.Close();
            }
            reports.Add("SaveError success");
        }
        catch (Exception ex)
        {
            reports.Add("Save Error Exception! " + ex.Message);
        }
    }

    public void Purge()
    {
        // delete cache!
        RemoveCache("c:\\osm\\cache");
        RemoveCache("f:\\osm\\cache");
    }

    private static void RemoveCache(string path)
    {
        if (!Directory.Exists(path))
            return;

        try
        {
            var downloadedMessageInfo = new DirectoryInfo(path);

            foreach (FileInfo file in downloadedMessageInfo.GetFiles())
            {
                file.Delete();
            }
            foreach (DirectoryInfo dir in downloadedMessageInfo.GetDirectories())
            {
                dir.Delete(true);
            }
        }
        catch (Exception)
        {

        }
    }
}